#include "xmlhelper.h"
#include <iostream>
#include <filesystem>


using namespace tinyxml2;

XmlHelper::XmlHelper() : m_root(nullptr) {
    // 创建声明
    m_doc.InsertEndChild(m_doc.NewDeclaration());
    // 创建根节点
    m_root = m_doc.NewElement("root");
    m_doc.InsertEndChild(m_root);
}

bool XmlHelper::loadFile(const std::string& filename) {
    if(std::filesystem::exists( std::filesystem::path(filename)))
    {
        XMLError result = m_doc.LoadFile(filename.c_str());
           if (result == XML_SUCCESS) {
               m_filename = filename;
               m_root = m_doc.FirstChildElement("root");
               if (!m_root) {
                   m_root = m_doc.NewElement("root");
                   m_doc.InsertEndChild(m_root);
               }
               return true;  // 文件存在且加载成功
           } else {
               m_filename = filename;
               return false; // 文件不存在或加载失败
           }
    }
    return false;
}

bool XmlHelper::saveFile(const std::string& filename) {
    std::string saveName = filename.empty() ? m_filename : filename;
    if (saveName.empty()) {
        return false;
    }
    return m_doc.SaveFile(saveName.c_str()) == XML_SUCCESS;
}

std::vector<std::string> XmlHelper::splitPath(const std::string& path) {
    std::vector<std::string> parts;
    std::stringstream ss(path);
    std::string part;

    while (std::getline(ss, part, '/')) {
        if (!part.empty()) {
            parts.push_back(part);
        }
    }

    return parts;
}

tinyxml2::XMLElement* XmlHelper::ensurePathExists(const std::string& path) {
    std::vector<std::string> parts = splitPath(path);
       if (parts.empty()) {
           return m_root;
       }

       XMLElement* current = m_root;

       for (const auto& part : parts) {
           XMLElement* child = current->FirstChildElement(part.c_str());
           if (!child) {
               child = m_doc.NewElement(part.c_str());
               current->InsertEndChild(child);  // 这行确保元素被添加到文档树
           }
           current = child;
       }

       return current;
}

bool XmlHelper::exists(const std::string& path) {
    std::vector<std::string> parts = splitPath(path);
    if (parts.empty()) {
        return true; // root always exists
    }

    XMLElement* current = m_root;

    for (const auto& part : parts) {
        current = current->FirstChildElement(part.c_str());
        if (!current) {
            return false;
        }
    }

    return true;
}

template<typename T>
T XmlHelper::read(const std::string& path, const T& defaultValue) {
    XMLElement* element = ensurePathExists(path);  // 确保路径存在

       const char* text = element->GetText();
       if (!text || strlen(text) == 0) {
           // 节点存在但没有值，设置默认值
           std::string defaultStr = toString(defaultValue);
           element->SetText(defaultStr.c_str());  // 这行设置文本值
           return defaultValue;
       }

       std::string value = text;
       return fromString<T>(value);
}

template<typename T>
bool XmlHelper::write(const std::string& path, const T& value) {
    try {
        XMLElement* element = ensurePathExists(path);
        element->SetText(toString(value).c_str());
        return true;
    } catch (...) {
        return false;
    }
}

std::string XmlHelper::toString() {
    XMLPrinter printer;
    m_doc.Print(&printer);
    return std::string(printer.CStr());
}

bool XmlHelper::remove(const std::string& path) {
    std::vector<std::string> parts = splitPath(path);
    if (parts.empty()) {
        return false; // 不能删除根节点
    }

    // 找到父节点
    std::vector<std::string> parentParts(parts.begin(), parts.end() - 1);
    std::string nodeName = parts.back();

    XMLElement* parent = m_root;
    for (const auto& part : parentParts) {
        parent = parent->FirstChildElement(part.c_str());
        if (!parent) {
            return false; // 父节点不存在
        }
    }

    XMLElement* toRemove = parent->FirstChildElement(nodeName.c_str());
    if (toRemove) {
        parent->DeleteChild(toRemove);
        return true;
    }

    return false;
}

void XmlHelper::debugPrintDocument()
{
    XMLPrinter printer;
    m_doc.Print(&printer);
    std::cout << "Current XML Document:\n" << printer.CStr() << std::endl;
}

// 字符串转换工具实现
template<typename T>
T XmlHelper::fromString(const std::string& str) {
    std::stringstream ss(str);
    T value;
    ss >> value;
    return value;
}

template<typename T>
std::string XmlHelper::toString(const T& value) {
    std::stringstream ss;
    ss << value;
    return ss.str();
}

// bool 类型的特化
template<>
bool XmlHelper::fromString<bool>(const std::string& str) {
    std::string lowerStr = str;
    std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(), ::tolower);

    if (lowerStr == "true" || lowerStr == "1" || lowerStr == "yes") {
        return true;
    } else if (lowerStr == "false" || lowerStr == "0" || lowerStr == "no") {
        return false;
    }

    // 尝试转换为数字
    std::stringstream ss(str);
    int intValue;
    ss >> intValue;
    return intValue != 0;
}

template<>
std::string XmlHelper::toString<bool>(const bool& value) {
    return value ? "true" : "false";
}

// string 类型的特化 - 直接返回
template<>
std::string XmlHelper::fromString<std::string>(const std::string& str) {
    return str;
}

template<>
std::string XmlHelper::toString<std::string>(const std::string& value) {
    return value;
}

// 显式实例化常用类型
template int XmlHelper::read<int>(const std::string&, const int&);
template double XmlHelper::read<double>(const std::string&, const double&);
template bool XmlHelper::read<bool>(const std::string&, const bool&);
template std::string XmlHelper::read<std::string>(const std::string&, const std::string&);

template bool XmlHelper::write<int>(const std::string&, const int&);
template bool XmlHelper::write<double>(const std::string&, const double&);
template bool XmlHelper::write<bool>(const std::string&, const bool&);
template bool XmlHelper::write<std::string>(const std::string&, const std::string&);
